import logging.config
import os
import threading
import zipfile
from datetime import datetime, timedelta
from os import path
from typing import List

from apscheduler.schedulers.blocking import BlockingScheduler

from apps.logger_config import get_log_conf, LOG_DIR

LOG_BACK_DIR = path.join(path.dirname(path.abspath(__file__)), r'..\..', 'log_back')
if not path.exists(LOG_BACK_DIR):
    os.mkdir(LOG_BACK_DIR)


def change_log_file_job():
    """
    修改日志文件名任务
    :return: None
    """
    logging.info("切换日志输出文件")
    logging.config.dictConfig(get_log_conf())


def pack_log_files_job():
    """
    前一天日志文件打包任务
    :return: None
    """
    logging.info('开始日志历史文件打包 开始时间：%s', datetime.now())
    log_files: List[str] = os.listdir(LOG_DIR)
    now = datetime.now()
    before_day = now - timedelta(days=1)
    file_prefix = before_day.strftime('%Y-%m-%d')
    log_files = [name for name in log_files if name.startswith(file_prefix)]
    if log_files is not None and log_files.__len__() != 0:
        file_path = path.join(LOG_BACK_DIR, "{prefix}.zip".format(prefix=file_prefix))
        if path.exists(file_path):
            return
        with zipfile.ZipFile(file_path, mode="w") as f:
            for log_file in log_files:
                f.write(path.join(LOG_DIR, log_file), log_file)
            f.close()
        # 删除历史文件
        for log_file in log_files:
            try:
                os.remove(path.join(LOG_DIR, log_file))
            except:
                pass
    logging.info('日志历史文件打包结束 结束时间：%s', datetime.now())


class ScheduleThread(threading.Thread):
    """
    任务调度线程
    """

    def __init__(self, *args, **kwargs):
        super(ScheduleThread, self).__init__(*args, **kwargs)
        self.schedule = BlockingScheduler()
        # 十五分钟更换一次日志文件名
        now = datetime.now()
        # 下一个15分钟
        minute = now.minute % 15
        self.schedule.add_job(change_log_file_job, 'interval', next_run_time=now + timedelta(minutes=minute),
                              minutes=15)
        # 每一天完成前一天日志文件打包压缩 每一天0点0分执行
        self.schedule.add_job(pack_log_files_job, 'cron', hour=0, minute=0)

    def run(self) -> None:
        logging.info('日志任务执行开始 %s', datetime.now())
        self.schedule.start()
